using System;
using System.Collections.Generic;
using System.Text;
using Castle.ActiveRecord;

namespace Hack.Authorization.Entities {
	/// <summary>
	/// Application entity.
	/// </summary>
	[ActiveRecord("DF_Application")]
	public class ApplicationEntity {

		#region Fields
		private Guid applicationId;
		private string name;
		private string description;
		private string password;
		private IList<UserEntity> users = new List<UserEntity>();
		private IList<RoleEntity> roles = new List<RoleEntity>();
		private string _email;
		private bool isBlocked;
		private DateTime createDate;
		private DateTime? blockedSince;
		private DateTime? unblockedSince;
		#endregion Fields

		#region Constructors
		/// <summary>
		/// Default constructor.
		/// </summary>
		public ApplicationEntity() {

		}

		/// <summary>
		/// Returns a new entity based in a data contract (gets from data store, then updates 
		/// data with the data contract data).
		/// </summary>
		/// <param name="application">Data Contract instance.</param>
		/// <returns>Returns the entity from the data store.</returns>
		public static ApplicationEntity FromContract(Application application) {
			ApplicationEntity entity = ActiveRecordMediator<ApplicationEntity>.FindByPrimaryKey(application.ApplicationId);
			entity.Description = application.Description;
			entity.Email = application.Email;
			entity.Name = application.Name;
			return entity;
		}

		/// <summary>
		/// Returns a data contract instance based in this entity.
		/// </summary>
		/// <returns>Returns the data contract instance.</returns>
		public Application ToContract() {
			Application app = new Application();
			app.ApplicationId = this.ApplicationId;
			app.BlockedSince = this.BlockedSince;
			app.CreateDate = this.CreateDate;
			app.Description = this.Description;
			app.Email = this.Email;
			app.IsBlocked = this.IsBlocked;
			app.Name = this.Name;
			app.UnblockedSince = this.UnblockedSince;

			return app;
		}
		#endregion Constructors

		#region Properties
		/// <summary>
		/// ApplicationId Property Name.
		/// </summary>
		public const string ApplicationIdProperty = "ApplicationId";
		/// <summary>
		/// Id of the customer.
		/// </summary>
		[PrimaryKey(PrimaryKeyType.Guid)]
		public Guid ApplicationId {
			get {
				return applicationId;
			}
			set {
				applicationId = value;
			}
		}

		/// <summary>
		/// Name Property Name.
		/// </summary>
		public const string NameProperty = "Name";
		/// <summary>
		/// Name of the application.
		/// </summary>
		[Property(Unique = true)]
		public string Name {
			get {
				return name;
			}
			set {
				name = value;
			}
		}

		/// <summary>
		/// Password Property Name.
		/// </summary>
		public const string PasswordProperty = "Password";
		/// <summary>
		/// Password so this application is allowed to authenticate against the service.
		/// </summary>
		[Property]
		public string Password {
			get {
				return password;
			}
			set {
				password = value;
			}
		}

		/// <summary>
		/// Description Property Name.
		/// </summary>
		public const string DescriptionProperty = "Description";
		/// <summary>
		/// Description of the application.
		/// </summary>
		[Property]
		public string Description {
			get {
				return description;
			}
			set {
				description = value;
			}
		}

		/// <summary>
		/// List of users of this application.
		/// </summary>
		[HasMany(typeof(UserEntity), Lazy = true, Cascade = ManyRelationCascadeEnum.SaveUpdate)]
		public virtual IList<UserEntity> Users {
			get {
				return users;
			}
			set {
				users = value;
			}
		}

		/// <summary>
		/// List of roles of this application.
		/// </summary>
		[HasMany(typeof(RoleEntity), Lazy = true, Cascade = ManyRelationCascadeEnum.SaveUpdate)]
		public virtual IList<RoleEntity> Roles {
			get {
				return roles;
			}
			set {
				roles = value;
			}
		}

		/// <summary>
		/// Email Property Name.
		/// </summary>
		public const string EmailProperty = "Email";
		/// <summary>
		/// E-mail of the responsible for managing this application. This information is needed for 
		/// password reseting purposes.
		/// </summary>
		[Property]
		public string Email {
			get {
				return _email;
			}
			set {
				_email = value;
			}
		}

		/// <summary>
		/// IsBlocked Property Name.
		/// </summary>
		public const string IsBlockedProperty = "IsBlocked";
		/// <summary>
		/// Indicates whether this application is blocked or not. This value is false when the
		/// application is created.
		/// </summary>
		[Property]
		public bool IsBlocked {
			get {
				return isBlocked;
			}
			set {
				isBlocked = value;
			}
		}

		/// <summary>
		/// CreateDate Property Name.
		/// </summary>
		public const string CreateDateProperty = "CreateDate";
		/// <summary>
		/// Indicates when this application was created. Defaults to DateTime.Now if not set.
		/// </summary>
		[Property]
		public DateTime CreateDate {
			get {
				return createDate;
			}
			set {
				createDate = value;
			}
		}

		/// <summary>
		/// BlockedSince Property Name.
		/// </summary>
		public const string BlockedSinceProperty = "BlockedSince";
		/// <summary>
		/// If the application is blocked, indicates when was the blocking date for this application.
		/// Otherwise this is null.
		/// This value defaults to null.
		/// </summary>
		[Property]
		public DateTime? BlockedSince {
			get {
				return blockedSince;
			}
			set {
				blockedSince = value;
			}
		}

		/// <summary>
		/// UnblockedSince Property Name.
		/// </summary>
		public const string UnblockedSinceProperty = "UnblockedSince";
		/// <summary>
		/// If the application is unblocked, indicates when was the unblocking date for this application.
		/// Otherwise this is null.
		/// This value defaults to the CreateDate.
		/// </summary>
		[Property]
		public DateTime? UnblockedSince {
			get {
				return unblockedSince;
			}
			set {
				unblockedSince = value;
			}
		}
		#endregion Properties

	}
}
